<?php

class Board extends CI_Controller {
     
	private $row;
	private $col;
	private $board;
	private $turn;
	private $str;
	private $count;
	
    function __construct() {
    	// Call the Controller constructor
	    parent::__construct();
	    session_start();
    } 
          
    public function _remap($method, $params = array()) {
	    // enforce access control to protected functions	
    	if(!isset($_SESSION['user']))
   			redirect('account/loginForm', 'refresh'); //Then we redirect to the index page again
 	    	
	    return call_user_func_array(array($this, $method), $params);
    }
    
    function index() {
    	//iniciates user session
		$user = $_SESSION['user'];
   		//loads models
    	$this->load->model('user_model');
    	$this->load->model('invite_model');
    	$this->load->model('match_model');
    	
    	$count = 0;
    	$board = array();
    	for($i = 0; $i < 6; $i++) {
    		$board[$i] = array();
    		for($j = 0; $j < 7; $j++) {
    			$board[$i][$j] = intval(0);
    			if($board[$i][$j] == 0) {
    				$count++;
    			}
    		}
    	}
    	
    	$turn = 0;
    	$match = null;
    	
    	//get username
    	$user = $this->user_model->get($user->login);
		//get invitation id
    	$invite = $this->invite_model->get($user->invite_id);
    	//checks status id from user
    	if($user->user_status_id == User::WAITING) {
    		//gets invitation id to get the otherUser
    		$invite = $this->invite_model->get($user->invite_id);
    		$otherUser = $this->user_model->getFromId($invite->user2_id);
    		$match = $this->match_model->get($user->match_id);
    	} else if ($user->user_status_id == User::PLAYING) {
    		$match = $this->match_model->get($user->match_id);
    		
    		$str = $match->board_state;
    	    		
    		if ($match->user1_id == $user->id) {
    			$otherUser = $this->user_model->getFromId($match->user2_id);
    			$turn = $otherUser->id;
    		} else {
    			$otherUser = $this->user_model->getFromId($match->user1_id);
    			$turn = $user->id;
    		}
    	}

    	$match_status = 1;
    	
    	$data['match'] = $match;
    	$data['match_status'] = $match_status;
    	$data['user'] = $user;
    	$data['otherUser'] = $otherUser;
    	$data['turnId'] = $turn;
    	$data['count'] = $count;
    	$data['conv'] = "";
    	$data['user1'] = $user->id;
    	
    	switch($user->user_status_id) {
    		case User::PLAYING:	
    			$data['status'] = 'playing';
    			break;
    		case User::WAITING:
    			$data['status'] = 'waiting';
    			break;
    	}
    	
    	$data['boardStateCur'] = $match->board_state;
    	$data['boardStateLast'] = $match->board_state;
    	$data['board'] = $board; 
 		$this->load->view('match/board', $data);
    }
    
    function play() {
    	$rows = 6;
    	$columns = 7;
    	
    	$button = intval($_POST['buttonId']);
    	if(isset($_POST['convId']))
    		$conv = $_POST['convId'];
    	else $conv = "";
    		
    	$this->load->model('user_model');
    	$this->load->model('match_model');
    	$this->load->model('invite_model');
    	
    	$user = $_SESSION['user'];

    	//selecting userid from user table
    	$user = $this->user_model->getExclusive($user->login);
    	if($user->user_status_id != User::PLAYING) {
    		$errormsg="Not in PLAYING state";
    	}
		
    	$invite = $this->invite_model->get($user->invite_id);
    	//checks status id from user
    	if($user->user_status_id == User::WAITING) {
    		//gets invitation id to get the otherUser
    		$invite = $this->invite_model->get($user->invite_id);
    		$otherUser = $this->user_model->getFromId($invite->user2_id);
    	} else if ($user->user_status_id == User::PLAYING) {
    		$match = $this->match_model->get($user->match_id);
    	}
    	
    	//selecting match id from user table
    	$match = $this->match_model->getExclusive($user->match_id);
       	$boardState = $match->board_state;
    	
       	if ($match->user1_id == $user->id) {
       		$otherUser = $this->user_model->getFromId($match->user2_id);
       		$turn = $otherUser->id;
       	} else {
       		$otherUser = $this->user_model->getFromId($match->user1_id);
       		$turn = $user->id;
       	}
       	
       	$data['boardStateLast'] = $boardState;
       	//breaking the string into arrays
       	$k = 0;
       	$count = 0;	
       	$board = array();
       	for($i = 0; $i < $rows; $i++){
       		$board[$i] = array();
       		for($j = 0; $j < $columns; $j++){
       			$board[$i][$j] = intval(substr($boardState, $k, 1));
       			$k++;
       			if($board[$i][$j] == intval(0)) {
       				$count++;
       			}
       		}
       	}
       	
       	$i = 5;
       	while(($board[$i][$button] != 0) && ($i > 0)) {
       		$i--;
       	}
       	
       	$count1 = 0;
       	if($board[$i][$button] == 0) {
	       	//sets the value from the current player
	       	if($user->id == $match->user1_id) 
	       		$board[$i][$button] = intval(1);
	       	else 
	       		$board[$i][$button] = intval(2);
	       	//transforms the matrix into a string again
	       	$boardState = ""; //empty string
	       	for($k = 0; $k < $rows; $k++){
	       		for($j = 0; $j < $columns; $j++){
	       			if($board[$k][$j] == intval(0)) {
	       				$count1++;
	       			}
	       			//$boardState receives values inside the cell [$i][$j]
	       			$boardState = $boardState . $board[$k][$j];	
	       		}
	       	}
       	}
       	
       	$hor = false;
       	$vert = false;
       	$diag1 = false;
       	$diag2 = false;
       	
       	for($i = 5; $i > 0; $i--){
       		for($j = 0; $j < 6; $j++){
       			if($board[$i][$j] != 0){
       				$hor = $this->verif_horizontal($i, $j, $board);
       				$vert = $this->verif_vertical($i, $j, $board);
       				$diag1 = $this->verif_diagonal_right($i, $j, $board);
       				$diag2 = $this->verif_diagonal_left($i, $j, $board);
       				if(($match->match_status_id == Match::ACTIVE) && ($hor || $vert || $diag1 || $diag2)) {
       					if($user->id == $match->user1_id){
       						$match->match_status_id = Match::U1WON;
       					} else {
       						$match->match_status_id = Match::U2WON;
       					}
       					
       					$this->match_model->updateStatus($match->id, $match->match_status_id);
       				}
       			}
       		}
       	}
       	
       	$this->match_model->updateBlob($match->id, $boardState);
       	
       	$data['user1'] = $match->user1_id;
       	$data['match'] = $match;
       	$data['user'] = $user;
       	$data['otherUser'] = $otherUser;
       	$data['turnId'] = $turn;
       	$data['count'] = $count;
       	 
       	switch($user->user_status_id) {
       		case User::PLAYING:
       			$data['status'] = 'playing';
       			break;
       		case User::WAITING:
       			$data['status'] = 'waiting';
       			break;
       	}

       	$data['conv'] = $conv;
       	$data['boardStateCur'] = $boardState; 
       	$data['match_status'] = intval($match->match_status_id);
       	$data['board'] = $board;
    	$this->load->view('match/board', $data);
    }

    function wait() {
    	$this->load->model('user_model');
    	$this->load->model('match_model');
    	
    	$user = $_SESSION['user'];
    	
    	$user = $this->user_model->get($user->login);
    	
    	$match = $this->match_model->getExclusive($user->match_id);
    	$boardState = $match->board_state;
    	$k = 0;
    	$count = 0;
    	for($i = 0; $i < 6; $i++){
    		for($j = 0; $j < 7; $j++){
    			if(intval(substr($boardState, $k, 1)) != intval(0)){
    				$count++;
    			}
    			$k++;
    		}
    	}
    	
		if($count % 2 == 0) {
			if($user->id == $match->user2_id) {
				echo json_encode(array('status'=>'yourTurn'));
			} else {
				echo json_encode(array('status'=>'othersTurn'));
			}
		} else {
			if($user->id == $match->user1_id){
				echo json_encode(array('status'=>'yourTurn'));
			} else {
				echo json_encode(array('status'=>'othersTurn'));
			}
		}		
    }
    
    function endGame() {
    	$this->load->model('user_model');
    	$this->load->model('match_model');
    	 
    	$user = $_SESSION['user'];
    	 
    	$user = $this->user_model->get($user->login);
    	 
    	$match = $this->match_model->getExclusive($user->match_id);
    	if ($match->user1_id == $user->id) {
    		$otherUser = $this->user_model->getFromId($match->user2_id);
    	} else {
    		$otherUser = $this->user_model->getFromId($match->user1_id);
    	}
    	
    	$this->user_model->updateStatus($user->id, User::AVAILABLE);
    	$this->user_model->updateStatus($otherUser->id, User::AVAILABLE);
    	redirect('arcade/index', 'refresh');
    }
    
    function postMsg() {
 		$this->load->library('form_validation');
 		$this->form_validation->set_rules('msg', 'Message', 'required');
 			
 		if($this->form_validation->run() == TRUE) {
 			$this->load->model('user_model');
 			$this->load->model('match_model');
 	
 			$user = $_SESSION['user'];
 				
 			$user = $this->user_model->getExclusive($user->login);
 			if($user->user_status_id != User::PLAYING) {
 				$errormsg="Not in PLAYING state";
 				goto error;
 			}
 	
 			$match = $this->match_model->get($user->match_id);
 			$msg = $this->input->post('msg');
 	
 			if($match->user1_id == $user->id)  {
 				$msg = $match->u1_msg == ''? $msg :  $match->u1_msg . "\n" . $msg;
 				$this->match_model->updateMsgU1($match->id, $msg);
 			} else {
 				$msg = $match->u2_msg == ''? $msg :  $match->u2_msg . "\n" . $msg;
 				$this->match_model->updateMsgU2($match->id, $msg);
 			}
 				
 			echo json_encode(array('status'=>'success'));	
 			return;
 		}
 	
 		$errormsg="Missing argument";
 			
 		error:
 			echo json_encode(array('status'=>'failure','message'=>$errormsg));
 	}
 	
 	function getMsg() {
 		$this->load->model('user_model');
 		$this->load->model('match_model');
 	
 		$user = $_SESSION['user'];
 	
 		$user = $this->user_model->get($user->login);
 		if($user->user_status_id != User::PLAYING) {
 			$errormsg="Not in PLAYING state";
 			goto error;
 		}
 		// start transactional mode
 		$this->db->trans_begin();
 	
 		$match = $this->match_model->getExclusive($user->match_id);
 	
 		if($match->user1_id == $user->id) {
 			$msg = $match->u2_msg;
 			$this->match_model->updateMsgU2($match->id,"");
 		} else {
 			$msg = $match->u1_msg;
 			$this->match_model->updateMsgU1($match->id,"");
 		}
 	
 		if($this->db->trans_status() === FALSE) {
 			$errormsg = "Transaction error";
 			goto transactionerror;
 		}
 			
 		// if all went well commit changes
 		$this->db->trans_commit();
 			
 		echo json_encode(array('status'=>'success','message'=>$msg));
 		return;
 	
 		transactionerror:
	 		$this->db->trans_rollback();
 	
 		error:
 			echo json_encode(array('status'=>'failure','message'=>$errormsg));
 	}
 	
 	function verif_vertical($row, $column, $board){
 		$num = 0;
 		 
 		while(($board[$row][$column] == 0) && ($row > 0))
 			$row--;
 		 
 		$player = $board[$row][$column];
 		for(; $row > 0; $row--){
 			if($player == $board[$row][$column]){
 				$num++;
 			}
 			else{
 				$num=0;
 				while(($board[$row][$column] == 0) && ($row > 0))
 					$row--;
 				$player = $board[$row][$column];
 			}
 			if($num == 4){
 				return TRUE;
 			}
 		}
 		return FALSE;
 	}   
 	
 	function verif_horizontal($row, $column, $board){
 		$num = 0;
 		 
 		while(($board[$row][$column] == 0) && ($column < 6))
 			$column++;
 		 
 		$player = $board[$row][$column];
 		for(; $column < 6; $column++){
 			if($player == $board[$row][$column]){
 				$num++;
 			}
 			else{
 				$num = 0;
 				while(($board[$row][$column] == 0) && ($column < 6))
 					$column++;
 				$player = $board[$row][$column];
 			}
 			if($num == 4){
 				return TRUE;
 			}
 		}
 		return FALSE;
 	}
 	 
 	function verif_diagonal_right($row, $column, $board){
 		$num = 0;
 		 
 		while(($board[$row][$column] == 0) && ($column < 6) && ($row > 0)) {
 			$column++;
 			$row--;
 		}
 		 
 		$player = $board[$row][$column];
 		for(;$row > 0 && $column < 6; $row--, $column++){
 			if($player == $board[$row][$column]){
 				$num++;
 			}
 			else{
 				$num = 0;
 				while(($board[$row][$column] == 0) && ($column < 6) && ($row > 0)) {
 					$column++;
 					$row--;
 				}
 				$player = $board[$row][$column];
 			}
 			if($num == 4){
 				return TRUE;
 			}
 		}
 		return FALSE;
 	}
 	
 	function verif_diagonal_left($row, $column, $board){
 		$num = 0;
 	
 		while(($board[$row][$column] == 0) && ($column > 0) && ($row > 0)) {
 			$column--;
 			$row--;
 		}
 	
 		$player = $board[$row][$column];
 		for(;$row > 0 && $column > 0; $row--, $column--){
 			if($player == $board[$row][$column]){
 				$num++;
 			}
 			else{
 				$num = 0;
 				while(($board[$row][$column] == 0) && ($column > 0) && ($row > 0)) {
 					$column--;
 					$row--;
 				}
 				$player = $board[$row][$column];
 			}
 			if($num == 4){
 				return TRUE;
 			}
 		}
 		return FALSE;
 	}
}